home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / prog / cenvi29.arj / MENUCTRL.LIB < prev    next >
Text File  |  1994-03-08  |  11KB  |  259 lines

  1. // MenuCtrl.lib - Functions for controlling PM menus.
  2. // ver.1
  3. //
  4. //**** GetMenu(): Retrieve handle to menu of window
  5. // SYNTAX: int GetMenu([int FrameWindowHandle[,int MenuWindowID]])
  6. // WHERE: FrameWindowHandle: Handle of frame window, if 0 or not supplied
  7. //                           default to active window
  8. //        MenuWindowID: Child ID of MenuWindow from within frame; if 0 or not
  9. //                      supplied then default to FID_MENU; likely values are:
  10.             #define FID_MENU     0x8005   // standard Frame window menu
  11.             #define FID_SYSMENU  0x8002   // standard Frame window system menu (upper-left corner)
  12. // RETURN: Return handle to menu for this window, or NULL if no menu
  13. //
  14. //
  15. //**** MenuCommand(): Send a menu command to window
  16. // SYNTAX: bool MenuCommand(int FrameWindowHandle,int MenuWindowID,string MenuID[,bool Post,[int Result]])
  17. //         bool MenuCommand(int FrameWindowHandle,int MenuWindowID,int MenuID[,bool Post,[int Result]])
  18. // WHERE: FrameWindowHandle: Handle of frame window, if 0 then default to active window
  19. //        MenuWindowID: Child ID of MenuWindow from within frame.  If this is
  20. //                      0 then will search all children of frame window that may
  21. //                      be menu, else specify specify ID, which will likely be FID_MENU or FID_SYSMENU
  22. //        MenuID: If integer then choose that menu id, els string and so
  23. //                will search through menu items for string with case
  24. //                insensitive match to start of string and ignoring the
  25. //                '~' character
  26. //        Post: Optional, True to WinPostMsg(), else WinSendMsg(); default False
  27. //        Result: If supplied then put result of WinSendMsg() or WinPostMsg() here
  28. // RETURN: Return FALSE if menu item wasn't found, else TRUE
  29. // MODIFY: set Result if supplied
  30. //
  31. //
  32. //**** FindMenuItem(): find menu item in menu of a frame window
  33. // SYNTAX: int MenuCommand(int FrameWindowHandle,int MenuWindowID,string MenuID,struct ItemData,int MenuHwnd)
  34. //         int MenuCommand(int FrameWindowHandle,int MenuWindowID,int MenuID,struct ItemData,int MenuHwnd)
  35. // WHERE: same as MenuCommand(), except ItemData set as in MenuQueryItem(), and
  36. //        MenuHwnd which is set to the menu hwnd in which this item was found
  37. // RETURN: MenuID, or 0 if not found
  38. //
  39. //
  40. //**** GetMenuItemCount()
  41. // SYNTAX: int GetMenuItemCount(int MenuHandle)
  42. // WHERE: MenuHandle: as retrieved by GetMenu()
  43. // RETURN: Return number of items in menu
  44. //
  45. //
  46. //**** GetMenuItemID(): Get Menu item ID based on ordinal position
  47. // SYNTAX: int GetMenuItemID(int MenuHandle,int Pos)
  48. // WHERE: MenuHandle: as retrieved by GetMenu()
  49. //        Pos: ordinal position of this menu item
  50. // RETURN: Return item ID, or -1 if MenuHandle is or index is invalid
  51. //
  52. //
  53. //**** GetMenuString(): Get string of a menu item
  54. // SYNTAX: string GetMenuString(int MenuHandle,int id)
  55. // WHERE: MenuHandle: as retrieved by GetMenu()
  56. //        id: integer ID of menu item
  57. // RETURN: Return string for this menu item, will not be NULL but may be ""
  58. //
  59. //
  60. //**** MenuQueryItem(): Get settings and attributes for menu item
  61. // SYNTAX: struct GetMenuState(int MenuHandle,int ItemID)
  62. // WHERE: MenuHandle: as retrieved by GetMenu()
  63. //        ItemID: menu-item by ID
  64. // RETURN: Return structure with the following member elements
  65. //          .Position
  66. //          .Style      see below
  67. //          .Attribute  see below
  68. //          .id         item iD
  69. //          .SubMenu    Handle to submenu
  70. //          .Item
  71. //    .Style can have following attributes
  72.    #define MIS_SUBMENU           0x0010
  73.    #define MIS_SEPARATOR         0x0004
  74.    #define MIS_BITMAP            0x0002
  75.    #define MIS_TEXT              0x0001
  76.    #define MIS_BUTTONSEPARATOR   0x0200
  77.    #define MIS_BREAK             0x0400
  78.    #define MIS_BREAKSEPARATOR    0x0800
  79.    #define MIS_SYSCOMMAND        0x0040   // send syscommand if selected
  80.    #define MIS_OWNERDRAW         0x0008
  81.    #define MIS_HELP              0x0080
  82.    #define MIS_STATIC            0x0100
  83.    #define MIS_MULTMENU          0x0020   // multiple choice submenu
  84.    #define MIS_GROUP             0x1000   // multiple choice group start
  85. //    .Attribute can have following attributes
  86.    #define MIA_HILITED                0x8000
  87.    #define MIA_CHECKED                0x2000
  88.    #define MIA_DISABLED               0x4000
  89.    #define MIA_FRAMED                 0x1000
  90.    #define MIA_NODISMISS              0x0020
  91. //
  92. //
  93. //**** FindMenuString(): Among menus and submenus, find ID for string
  94. // SYNTAX: int FindMenuString(int MenuHandle,string PartialString,struct ItemData,int MenuHwnd)
  95. // WHERE: MenuHandle: as retrieved by GetMenu()
  96. //        PartialString: string to match menu (case-insensitive) up up to length
  97. //                       of this string
  98. //        ItemData: if item found, will be set as returned by MenuQueryItem()
  99. //        MenuHwnd: if found, then set this to handle of menu found
  100. // RETURN: 0 if not found, else ID of matching menu item
  101. // MODIFY: Modify ItemData if menu item found
  102. // NOTE: This compares menu item string without the special ~ character, and
  103. //       so this is not very fast
  104. //
  105. //
  106.  
  107.  
  108. #include <WinMsg.lib>
  109. #include <GiveMem.lib>
  110. #define HWND_DESKTOP 1
  111.  
  112. _GetActiveWindow()
  113. {
  114.    #define ORD_WIN32QUERYACTIVEWINDOW  799
  115.    return PMDynamicLink("PMWIN",ORD_WIN32QUERYACTIVEWINDOW,BIT32,CDECL,HWND_DESKTOP);
  116. }
  117.  
  118. GetMenu(pFrameHandle,pMenuWindowID)
  119. {
  120.    lFHwnd = ( va_arg() && pFrameHandle ) ? pFrameHandle : _GetActiveWindow() ;
  121.    lMenuHwndID = ( 1 < va_arg() && pMenuWindowID ) ? pMenuWindowID : FID_MENU ;
  122.    #define ORD_WIN32WINDOWFROMID 899
  123.    return PMDynamicLink("PMWIN",ORD_WIN32WINDOWFROMID,BIT32,CDECL,lFHwnd,lMenuHwndID);
  124. }
  125.  
  126. GetMenuItemCount(pMenu)
  127. {
  128.    #define MM_QUERYITEMCOUNT  0x0184
  129.    return ( 0xFFFF & WinSendMsg(pMenu,MM_QUERYITEMCOUNT,0,0) );
  130. }
  131.  
  132. GetMenuItemID(pMenu,pPos)
  133. {
  134.    #define MM_ITEMIDFROMPOSITION      0x0190
  135.    lID = ( 0xFFFF & WinSendMsg(pMenu,MM_ITEMIDFROMPOSITION,pPos,0) );
  136.    return ( 0xFFFF == lID ? -1 : lID );
  137. }
  138.  
  139. MenuQueryItem(pMenu,pItemID)
  140. {
  141.    BLObSize(lRetBLOb,16);
  142.    memset(lRetBLOb,0,16);
  143.    poke(lSharedMem = GiveMemoryToWindow(pMenu),lRetBLOb,16);
  144.    #define MM_QUERYITEM    0x0182
  145.    #define MM_STARTMENUMODE           0x0185
  146.    #define MM_ENDMENUMODE             0x0186
  147.    WinSendMsg(pMenu,MM_QUERYITEM,MakeLongFromShorts(pItemID,True),lSharedMem);
  148.    lRetBLOb = peek(lSharedMem,16);
  149.    lRet.Position = BLObGet(lRetBLOb,0,SWORD16);
  150.    lRet.Style = BLObGet(lRetBLOb,2,UWORD16);
  151.    lRet.Attribute = BLObGet(lRetBLOb,4,UWORD16);
  152.    lRet.id = BLObGet(lRetBLOb,6,UWORD16);
  153.    lRet.SubMenu = BLObGet(lRetBLOb,8,UWORD32);
  154.    lRet.Item = BLObGet(lRetBLOb,12,UWORD32);
  155.    return lRet;
  156. }
  157.  
  158. GetMenuString(pMenu,pID)
  159. {
  160.    #define MM_QUERYITEMTEXT   0x018B
  161.    lSharedMem = GiveMemoryToWindow(pMenu);
  162.    if ( lTextLen = WinSendMsg(pMenu,MM_QUERYITEMTEXT,MakeLongFromShorts(pID,1000),lSharedMem) )
  163.       lString = peek(lSharedMem,lTextLen);
  164.    lString[lTextLen] = '\0';
  165.    return lString;
  166. }
  167.  
  168. FindMenuString(pMenu,pPartialString,pItemData,pFoundMenuHwnd)
  169. {
  170.    lPartialLen = strlen(pPartialString);
  171.    lCount = GetMenuItemCount(pMenu);
  172.    for ( lOrd = 0; lOrd < lCount; lOrd++ ) {
  173.       if ( -1 != (lMenuID = GetMenuItemID(pMenu,lOrd)) ) {
  174.          lMenu = MenuQueryItem(pMenu,lMenuID);
  175.          if ( lMenu.Style & MIS_SUBMENU ) {
  176.             // this is a submenu, so check down this submenu
  177.             if ( lMenuID = FindMenuString(lMenu.SubMenu,pPartialString,pItemData,pFoundMenuHwnd) ) {
  178.                return lMenuID;
  179.             }
  180.          } else {
  181.             // get string for this item, and compare against partial string with all '&'
  182.             lMenuString = GetMenuString(pMenu,lMenuID);
  183.             if ( lMenuString[0] ) {
  184.                // remove all '~' characters
  185.                lFindTilde = lMenuString;
  186.                while ( lFindTilde = strchr(lFindTilde,'~') )
  187.                   strcpy(lFindTilde,lFindTilde+1);
  188.                // compare new found string against our source
  189.                if ( !strnicmp(lMenuString,pPartialString,lPartialLen) ) {
  190.                   // YEA!!!! it is found
  191.                   pFoundMenuHwnd = pMenu;
  192.                   pItemData = lMenu;
  193.                   return lMenuID;
  194.                }
  195.             }
  196.          }
  197.       }
  198.    }
  199.    return 0;
  200. }
  201.  
  202. FindMenuItem(pFrameHwnd,pMenWinID,pMenuID,pItemData,pFoundMenuHwnd)
  203. {
  204.    lFHwnd = pFrameHwnd ? pFrameHwnd : _GetActiveWindow() ;
  205.    lMenuID = 0;   // assume failure
  206.  
  207.    if ( pMenWinID ) {
  208.       // try on this one window ID
  209.       if ( lMenuHwnd = GetMenu(lFHwnd,pMenWinID) ) {
  210.          pFoundMenuHwnd = lMenuHwnd;
  211.          lMenuID = ( 0 == DataDimension(pMenuID) )
  212.                  ? (pItemData = MenuQueryItem(lMenuHwnd,pMenuID)).id
  213.                  : FindMenuString(lMenuHwnd,pMenuID,pItemData,pFoundMenuHwnd);
  214.       }
  215.    } else {
  216.       // must try all children
  217.       #define ORD_WIN32BEGINENUMWINDOWS   702
  218.       #define ORD_WIN32GETNEXTWINDOW      756
  219.       #define ORD_WIN32ENDENUMWINDOWS     737
  220.       lEnumHandle = DynamicLink("PMWIN",ORD_WIN32BEGINENUMWINDOWS,BIT32,CDECL,lFHwnd);
  221.       while ( lChild = DynamicLink("PMWIN",ORD_WIN32GETNEXTWINDOW,BIT32,CDECL,lEnumHandle) ) {
  222.          pFoundMenuHwnd = lChild;
  223.          if ( lMenuID = ( 0 == DataDimension(pMenuID) )
  224.                       ? (pItemData = MenuQueryItem(lMenuHwnd,pMenuID)).id
  225.                       : FindMenuString(lChild,pMenuID,pItemData,pFoundMenuHwnd) )
  226.             break;
  227.       }
  228.       DynamicLink("PMWIN",ORD_WIN32ENDENUMWINDOWS,BIT32,CDECL,lEnumHandle)
  229.    }
  230.    return lMenuID;
  231. }
  232.  
  233. MenuCommand(pFrameHwnd,pMenWinID,pMenuID,pPost,pResult)
  234. {
  235.    lFHwnd = pFrameHwnd ? pFrameHwnd : _GetActiveWindow() ;
  236.    if ( !(lMenuID = FindMenuItem(lFHwnd,pMenWinID,pMenuID,lItemData,lFoundMenuHwnd)) )
  237.       return FALSE;
  238.  
  239.    // send menu_select message
  240.    // #define WM_MENUSELECT   0x34
  241.    // if ( !WinSendMsg(lFHwnd,WM_MENUSELECT,MakeLongFromShorts(lMenuID,True),lFoundMenuHwnd) )
  242.    //    return FALSE;
  243.  
  244.    // item info will tell whether messase is wm_command or wm_syscommand
  245.    #define WM_COMMAND      0x20
  246.    #define WM_SYSCOMMAND   0x21
  247.    lMsg = (lItemData.Style & MIS_SYSCOMMAND) ? WM_SYSCOMMAND : WM_COMMAND ;
  248.    #define CMDSRC_MENU 2
  249.    lParam2 = MakeLongFromShorts(CMDSRC_MENU,False);
  250.  
  251.    lResult = ( 3 < va_arg() && pPost )
  252.            ? WinPostMsg(lFHwnd,lMsg,lMenuID,lParam2)
  253.            : WinSendMsg(lFHwnd,lMsg,lMenuID,lParam2) ;
  254.    if ( 4 < va_arg() )
  255.       pResult = lResult;
  256.    return(TRUE);
  257. }
  258.  
  259.